package com.haredot.desensitize;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.haredot.desensitize.enums.DesensitizeType;

import java.io.IOException;
import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@JsonSerialize(using = JsonDesensitize.ToDesensitizeSerializer.class)
@JacksonAnnotationsInside
public @interface JsonDesensitize {

    DesensitizeType type() ;

    String symbol() default "*" ;

    int symbolLength() default -1 ;

    String pattern() default "" ;

    int group() default  0 ;

    class ToDesensitizeSerializer extends JsonSerializer<String> implements ContextualSerializer {

        private JsonDesensitize jsonDesensitize;

        @Override
        public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {

            switch (jsonDesensitize.type()) {
                case TEL -> gen.writeString(DesensitizeType.tel(value, jsonDesensitize.symbol()));
                case EMAIL ->
                        gen.writeString(DesensitizeType.email(value, jsonDesensitize.symbol(), jsonDesensitize.symbolLength()));
                case ID_CARD -> gen.writeString(DesensitizeType.idCard(value, jsonDesensitize.symbol()));
                case PASSWORD -> gen.writeString(DesensitizeType.password(value));
                case CUSTOM ->
                        gen.writeString(DesensitizeType.custom(value, jsonDesensitize.pattern(), jsonDesensitize.symbol(), jsonDesensitize.symbolLength(), jsonDesensitize.group()));
            }
        }

        @Override
        public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {

            jsonDesensitize = property.getAnnotation(JsonDesensitize.class);

            if (jsonDesensitize != null) {
                return this;
            }
            return prov.findNullKeySerializer(property.getType(), property);
        }
    }
}
